<template>
  <div class="report-component-container">
    <common-header :title="isEdit ? '编辑组件' : '新增组件'">
      <el-button
        type="primary"
        @click="persistenceData"
        :loading="isPersistenceLoading"
        v-show="isEdit"
        v-hasPermi="['system:reportparts:editSubgroup']"
        >保存
      </el-button>
      <el-button
        type="primary"
        @click="persistenceData"
        :loading="isPersistenceLoading"
        v-show="!isEdit"
        v-hasPermi="['system:reportparts:addSubgroup']"
        >保存
      </el-button>
    </common-header>
    <div class="report-component-body-wrap">
      <div class="report-component-info-wrap">
        <common-group-title title="基本配置" />
        <el-form
          ref="infoForm"
          :model="form"
          :rules="formRules"
          label-width="100px"
        >
          <!--          <el-form-item label="ID">
            {{ form.id }}
          </el-form-item>-->

          <el-row>
            <el-col :span="24">
              <el-form-item label="组件名称" prop="name">
                <common-input
                  v-model="form.name"
                  :maxlength="16"
                  placeholder="请输入"
                ></common-input>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="分组名称">
                <el-cascader
                  v-model="form.type"
                  :options="groupData"
                  :show-all-levels="false"
                  :props="{
                    expandTrigger: 'hover',
                    label: 'name',
                    value: 'id',
                    checkStrictly: true,
                    emitPath: false,
                  }"
                >
                </el-cascader>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="组件描述">
            <common-input
              type="textarea"
              v-model="form.description"
            ></common-input>
          </el-form-item>
        </el-form>
        <el-form
          label-width="100px"
          ref="dataSourceForm"
          :model="form"
          :rules="dataRules"
        >
          <el-row>
            <el-col :span="12">
              <el-form-item label="数据类型" prop="sourceType">
                <el-select v-model="form.sourceType" @change="sourceTypeChange">
                  <el-option
                    v-for="(item, index) in dbTypeList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="数据来源" prop="datasource">
                <el-select v-model="form.datasource" @change="dataSourceChange">
                  <el-option
                    v-for="(item, index) in dataSourceList"
                    :key="item.key"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <common-group-title title="图表选择" />
        <el-form
          label-width="100px"
          ref="chartForm"
          :model="form"
          :rules="formRules"
        >
          <el-row>
            <el-col :span="12">
              <el-form-item label="图表分类" prop="chartType">
                <span style="position: relative">
                  <el-select v-model="form.chartType" @change="chartTypeChange">
                    <el-option
                      v-for="item in chartTree"
                      :key="item.type"
                      :label="item.name"
                      :value="item.type"
                    ></el-option>
                  </el-select>
                  <div
                    v-if="prompt"
                    style="
                      font-size: 12px;
                      color: #f56c6c;
                      position: absolute;
                      top: 32px;
                      left: 0;
                      line-height: 12px;
                    "
                  >
                    {{ prompt }}
                  </div>
                </span>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="图表模板" prop="echartId">
                <el-select
                  v-model="form.echartId"
                  @change="chartTemplateChange"
                >
                  <el-option
                    v-for="item in chartList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>

        <template v-if="form.sourceType === 'MYSQL'">
          <common-group-title title="MYSQL" />
          <el-form
            ref="sqlForm"
            :model="sqlForm"
            label-width="100px"
            :rules="dataRules"
          >
            <el-form-item label="SQL语句" prop="datasql">
              <common-input
                type="textarea"
                :rows="4"
                :maxlength="4000"
                :placeholder="`示例: select xx from ark_api_interface where create_time > '##timeinterval##' group by domain`"
                v-model="sqlForm.datasql"
              ></common-input>
            </el-form-item>
          </el-form>
        </template>
        <template v-if="form.sourceType === 'ES'">
          <common-group-title title="ES" />
          <el-form
            ref="esForm"
            :model="esForm"
            label-width="100px"
            :rules="dataRules"
          >
            <el-form-item label="统计字段">
              <div class="field-row" v-for="item in statistics">
                <el-select
                  v-model="item.field"
                  style="margin-right: 8px; width: calc(100% - 22px)"
                  @change="statisticsChange"
                >
                  <el-option
                    v-for="item in esStatisticsFieldList"
                    :key="item.key"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
                <el-button
                  type="text"
                  icon="el-icon-delete"
                  style="color: #f56c6c"
                  @click="delGroupData(item)"
                ></el-button>
              </div>
              <el-button
                v-if="statistics.length < 1"
                type="primary"
                plain
                @click="addStatistics"
                >新增
              </el-button>
            </el-form-item>

            <el-form-item label="指标字段">
              <div class="field-row" v-for="item in aggregation">
                <el-select
                  v-model="item.aggType"
                  style="margin-right: 8px; width: calc(50% - 15px)"
                >
                  <el-option
                    v-for="item in aggregationList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>

                <el-select
                  v-model="item.field"
                  v-if="item.aggType !== 'count'"
                  style="margin-right: 8px; width: calc(50% - 15px)"
                >
                  <el-option
                    v-for="item in esIsShowFieldList"
                    :key="item.key"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
                <el-button
                  type="text"
                  icon="el-icon-delete"
                  style="color: #f56c6c"
                  @click="delGroupData(item)"
                ></el-button>
              </div>
              <el-button
                v-if="aggregation.length < 1"
                type="primary"
                plain
                @click="addAggregation"
                >新增
              </el-button>
            </el-form-item>

            <el-form-item label="条件">
              <div class="field-row" v-for="item in esForm.where.chd">
                <el-select
                  v-model="item.data.fieldName"
                  placeholder="字段类型"
                  style="margin-right: 8px; width: calc(50% - 15px)"
                >
                  <el-option
                    v-for="item in esIsSearchFieldList"
                    :key="item.key"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>

                <el-select
                  v-model="item.data.operator"
                  placeholder="操作符号"
                  style="margin-right: 8px; width: 60px"
                >
                  <el-option
                    v-for="item in sqlExpressionList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>

                <common-input
                  v-model="item.data.value"
                  placeholder="字段值"
                  style="margin-right: 8px; width: calc(50% - 83px)"
                ></common-input>

                <el-button
                  type="text"
                  icon="el-icon-delete"
                  style="color: #f56c6c"
                  @click="delCondition(item)"
                ></el-button>
              </div>
              <el-button type="primary" plain @click="addCondition"
                >新增
              </el-button>
            </el-form-item>
          </el-form>
        </template>
        <template v-if="form.sourceType === 'API'">
          <common-group-title title="API" />
          <el-form
            ref="apiForm"
            :model="apiForm"
            label-width="100px"
            :rules="dataRules"
          >
            <el-form-item label="URL" prop="url">
              <common-input
                type="textarea"
                v-model="apiForm.url"
              ></common-input>
            </el-form-item>
            <el-form-item label="参数" prop="param">
              <common-input
                type="textarea"
                v-model="apiForm.param"
              ></common-input>
            </el-form-item>
          </el-form>
        </template>

        <div
          style="
            width: 100%;
            display: flex;
            justify-content: flex-end;
            align-items: center;
          "
        >
          <el-button
            type="primary"
            plain
            @click="getData"
            :loading="isGetDataLoading"
            >获取数据
          </el-button>
        </div>

        <common-group-title title="字段配置" />
        <el-form
          ref="mapperForm"
          :model="mapper"
          label-width="100px"
          :rules="mapperRules"
          v-if=""
        >
          <!--                    <el-form-item label="字段预览">
                                <el-tag style="margin-right: 4px" v-for="field in fieldList">{{ field.fieldName }}</el-tag>
                              </el-form-item>-->
          <!--          <el-form-item label="维度字段" v-if="mapper.type === 'dimensions'" prop="dimensions">
                      &lt;!&ndash;                      <common-input v-model="mapper.dimensions"></common-input>&ndash;&gt;
                      {{ mapper.dimensions }}
                    </el-form-item>-->

          <el-row>
            <el-col :span="12">
              <el-form-item label="类目字段" prop="xField">
                <el-select v-model="mapper.xField" @change="handleDimensions">
                  <el-option
                    v-for="item in fieldList"
                    :key="item.fieldName"
                    :label="item.fieldDescribe"
                    :value="item.fieldName"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="数值字段" prop="yField">
                <el-select v-model="mapper.yField" @change="handleDimensions">
                  <el-option
                    v-for="item in fieldList"
                    :key="item.fieldName"
                    :label="item.fieldDescribe"
                    :value="item.fieldName"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>

        <!--        <el-button type="primary" plain @click="renderChart" v-if="fieldList.length">预览图表</el-button>-->
      </div>
      <div class="line"></div>
      <div class="report-component-preview-wrap">
        <!--        <common-group-title title="数据预览"/>
                <div class="component-preview-table-wrap">
                  <common-table :data="dataset.source">
                    <el-table-column v-for="field in fieldList" :prop="`${field.fieldName}`"
                                     :label="field.fieldDescribe"></el-table-column>
                  </common-table>
                </div>-->

        <common-group-title title="图表预览" />
        <div class="component-chart-wrap">
          <base-chart ref="chartDom" :option="option"></base-chart>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
  subgroup_datasourceList,
  subgroup_selectIndexList,
  subgroup_echartTemplate,
  subgroup_test,
  getComponentInfo,
  subgroup_edit,
  subgroup_add,
} from "@/api/management/echart/subgroup";
import { sqlExpressionList } from "@/dictionary/database";
import BaseChart from "@/components/EChart/components/BaseChart";

export default {
  name: "chartConfig",
  components: {
    BaseChart,
  },
  props: {
    groupData: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      isGetDataLoading: false,
      isPersistenceLoading: false,
      isEdit: false,
      form: {
        id: null,
        name: "", // 组件名称
        description: "", // 组件描述
        sourceType: "", // 数据类型
        datasource: "", // 数据来源
        echartId: "", // 图表模板id
        chartType: "", // 图表模板分类id
        type: "", // 上级分类id
        typeName: "", // 上级分类名称
      }, //
      formRules: {
        name: [{ required: true, message: "请输入组件名称", trigger: "blur" }],
        chartType: [
          { required: true, message: "请选择图表分类", trigger: "change" },
        ],
        echartId: [
          { required: true, message: "请选择图表模板", trigger: "change" },
        ],
        /*  dimensions: [
            { required: true, message: '请输入维度定义', trigger: 'blur' }
          ]*/
      },
      mapperRules: {
        xField: [
          { required: true, message: "请选择类目字段", trigger: "change" },
        ],
        yField: [
          { required: true, message: "请选择数值字段", trigger: "change" },
        ],
      },
      dataRules: {
        sourceType: [
          { required: true, message: "请选择数据类型", trigger: "change" },
        ],
        datasource: [
          { required: true, message: "请选择数据来源", trigger: "change" },
        ],
        datasql: [
          { required: true, message: "请输入SQL语句", trigger: "blur" },
        ],
        url: [{ required: true, message: "请输入URL地址", trigger: "blur" }],
      },
      sqlForm: {
        datasql: "", //select request_method as method,count(1) as count from ark_sys_oper_log where request_method is not null and oper_time > '##timeinterval##' group by request_method
      }, // sql配置项
      esForm: {
        indexPrefix: "", //this.form.databaseName
        limit: 10,
        group: [
          /*{
            field: '',
            aggType: 'terms',// terms 统计字段   指标类型列表
            size: 10,// 固定参数
            sort: true,// 固定参数
            type:''
          }*/
        ],
        where: {
          chd: [
            /*{
              fieldName: '',
              value: '',
              operator: 'EQ'
            }*/
          ],
          operate: "AND",
        },
      }, // es配置项
      apiForm: {
        url: "",
        param: "",
      }, // api配置项
      mapper: {
        type: "dimensions", //
        dimensions: "",
        xField: "", // 维度字段 最总会合并到 mapper.dimensions 里面  X轴在前 Y轴在后
        yField: "",
      },
      dbTypeList: [], // 数据类型
      esStatisticsFieldList: [], // 数据类型为ES时的统计字段列表
      esIsShowFieldList: [], // 数据类型为ES时的指标字段列表
      esIsSearchFieldList: [], // 数据类型为ES时的条件字段列表
      chartTree: [], // 所有图表数据 待分类
      aggregationList: [
        { label: "计数", value: "count" },
        { label: "平均数", value: "avg" },
        { label: "最大值", value: "max" },
        { label: "最小值 ", value: "min" },
        { label: "合计 ", value: "sum" },
      ], // 指标类型列表
      sqlExpressionList: sqlExpressionList,
      dataset: {
        dimensions: [],
        source: [],
      },
      fieldList: [
        /*{
          fieldName: 'name',
          fieldType: 'String',
          fieldDescribe: '季度'
        }*/
      ], // 数据字段列表
      option: {
        dataset: {
          dimensions: [],
          source: [],
        },
        series: [],
      },
    };
  },
  computed: {
    statistics: function () {
      return this.esForm.group.filter((item) => item.aggType === "terms");
    }, //
    aggregation: function () {
      return this.esForm.group.filter((item) => item.aggType !== "terms");
    },
    chartList: function () {
      let chartType = this.chartTree.find(
        (c) => c.type === this.form.chartType
      );
      return chartType ? chartType.reportEchartsList : [];
    },
    dataSourceList: function () {
      let item = this.dbTypeList.find(
        (item) => item.value === this.form.sourceType
      );
      return item ? item.children : [];
    }, //数据类型下 数据源列表
    prompt: function () {
      let ct = this.chartTree.find((c) => c.type === this.form.chartType);
      return ct?.remark;
    },
  },
  watch: {
    "mapper.dimensions": function () {
      this.dataset.dimensions = this.mapper.dimensions
        .split(",")
        .reduce((r, c) => {
          r.push(c.trim());
          return r;
        }, []);
      this.renderChart();
    },
  },
  methods: {
    statisticsChange(v) {
      // 只有统计字段才需要带类型
      let statistics = this.esStatisticsFieldList.find((es) => es.value === v);
      this.esForm.group.map((item) => {
        if (statistics.value === item.field) {
          item.type = statistics.type;
        }
      });
    },
    /**
     * 获取数据类型列表
     * 数据类型包含类型下面的数据源列表
     */
    getDataSourceList() {
      subgroup_datasourceList({})
        .then((res) => {
          if (res && res.code === 200) {
            this.dbTypeList = res.data.reduce((r, c) => {
              r.push({
                label: c.name,
                value: c.type,
                children: c.reportDatasourceVoList.reduce((dr, dc) => {
                  dr.push({
                    label: dc.datasoureName,
                    value: dc.id,
                    key: dc.id,
                    ...dc,
                  });
                  return dr;
                }, []),
              });
              return r;
            }, []);
            if (this.dbTypeList.length) {
              this.form.sourceType = this.dbTypeList[0].value;
            }
          } else {
            this.dbTypeList = [];
          }
        })
        .catch((err) => {
          this.dbTypeList = [];
        });
    },
    /**
     * 获取图表数据
     */
    getChartList() {
      subgroup_echartTemplate({})
        .then((res) => {
          if (res && res.code === 200) {
            this.chartTree = res.data;
          } else {
            this.chartTree = [];
          }
        })
        .catch((err) => {
          this.chartTree = [];
        });
    },
    getComponentInfoById(id) {
      getComponentInfo({ id })
        .then((res) => {
          if (res && res.code === 200) {
            this.initComponentConfigData(res.data);
          } else {
            console.log("获取失败: ", res);
          }
        })
        .catch((err) => {
          console.log("获取异常: ", err);
        });
    },
    initComponentConfigData(data) {
      this.form.id = data.id;
      this.form.name = data.name;
      this.form.description = data.description;
      this.form.sourceType = data.reportDatasource
        ? data.reportDatasource.datasourceType
        : "";
      this.form.datasource = data.datasource;
      this.form.chartType = data.echart.type;
      this.form.echartId = data.echartId;
      this.chartTemplateChange();
      // this.form.type = data.type

      this.dataSourceChange();

      let parameter = {};

      try {
        parameter = JSON.parse(data.parameter);
      } catch (e) {
        console.log("转换图表配置项异常");
        console.log("图表配置项: ", data.parameter);
      }

      if (this.form.sourceType === "MYSQL") {
        this.sqlForm.datasql =
          parameter.sql && parameter.sql.datasql ? parameter.sql.datasql : "";
      }

      if (this.form.sourceType === "API") {
        this.apiForm.url =
          parameter.api && parameter.api.url ? parameter.api.url : "";
        this.apiForm.param =
          parameter.api && parameter.api.param ? parameter.api.param : "";
      }

      if (this.form.sourceType === "ES") {
        if (parameter.es && parameter.es.group) {
          this.esForm.group = parameter.es.group;
        } else {
          this.esForm.group = [];
        }

        if (parameter.es && parameter.es.where && parameter.es.where.chd) {
          this.esForm.where.chd = parameter.es.where.chd;
        } else {
          this.esForm.where.chd = [];
        }
      }

      this.mapper.type =
        parameter.mapper && parameter.mapper.type
          ? parameter.mapper.type
          : "dimensions";
      this.mapper.dimensions =
        parameter.mapper && parameter.mapper.dimensions
          ? parameter.mapper.dimensions
          : "";

      let fields = this.mapper.dimensions.split(",");
      if (fields.length > 0) this.mapper.xField = fields[0].trim();
      if (fields.length > 1) this.mapper.yField = fields[1].trim();

      this.getData();
    },

    /**
     * 数据源切换事件
     * @param source
     */
    dataSourceChange(source) {
      if (this.form.sourceType === "ES") {
        let api = this.dataSourceList.find(
          (ds) => ds.value === this.form.datasource
        );
        this.esForm.indexPrefix = api.databaseName;
        this.getEsFieldList();
      }
      if (this.form.sourceType === "API") {
        let api = this.dataSourceList.find(
          (ds) => ds.value === this.form.datasource
        );
        this.apiForm.url = api.url;
      }

      // 重置数据
      this.resetChartData();
      // 重置映射配置
      this.resetMapperConfig();
    },
    /**
     * 获取es数据源下 索引字段列表
     */
    getEsFieldList() {
      subgroup_selectIndexList({
        dataSourceId: this.form.datasource,
      })
        .then((res) => {
          //1.统计字段
          this.esStatisticsFieldList = res.data
            .filter(function (item) {
              return item.isStatistics == 0;
            })
            .reduce((r, c) => {
              r.push({
                label: c.columnAlias || c.columnName,
                value: c.columnName,
                key: c.id,
                type: c.columnType,
              });
              return r;
            }, []);
          //2.指标字段
          this.esIsShowFieldList = res.data
            .filter(function (item) {
              return item.isShow == 0;
            })
            .reduce((r, c) => {
              r.push({
                label: c.columnAlias || c.columnName,
                value: c.columnName,
                key: c.id,
              });
              return r;
            }, []);
          //3.条件字段
          this.esIsSearchFieldList = res.data

            .filter(function (item) {
              return item.isSearch == 0;
            })
            .reduce((r, c) => {
              r.push({
                label: c.columnAlias || c.columnName,
                value: c.columnName,
                key: c.id,
              });
              return r;
            }, []);
        })
        .catch((err) => {
          console.log("err: ", err);
        });
    },
    addStatistics() {
      this.esForm.group.push({
        id: new Date().getTime(),
        field: "",
        aggType: "terms", // terms 统计字段   指标类型列表
        size: 10, // 固定参数
        sort: true, // 固定参数
        type: "", // 字段类型
      });
    },
    addAggregation() {
      this.esForm.group.push({
        id: new Date().getTime(),
        field: "",
        aggType: "count", // terms 统计字段   指标类型列表
        size: 10, // 固定参数
      });
    },
    delGroupData(item) {
      let index = this.esForm.group.findIndex((g) => g.id === item.id);
      if (index !== -1) this.esForm.group.splice(index, 1);
    },
    addCondition() {
      this.esForm.where.chd.push({
        id: new Date().getTime(),
        data: {
          fieldName: "",
          value: "",
          operator: "EQ",
        },
        operate: "AND",
      });
    },
    delCondition(item) {
      let index = this.esForm.where.chd.findIndex((g) => g.id === item.id);
      if (index !== -1) this.esForm.where.chd.splice(index, 1);
    },
    getData() {
      Promise.all([this.validateDataSource()])
        .then((res) => {
          let params = {
            sourceType: this.form.sourceType,
            datasource: this.form.datasource,
            parameter: JSON.stringify({
              sql: {
                ...this.sqlForm,
              },
              es: {
                ...this.esForm,
              },
              api: {
                ...this.apiForm,
              },
            }),
          };
          if (!this.isGetDataLoading) {
            let msg = "";
            if (this.esForm.where.chd && this.esForm.where.chd.length) {
              this.esForm.where.chd.forEach((item) => {
                if (item.data.fieldName === "") {
                  msg = "请选择字段类型";
                } else {
                  if (item.data.value === "") {
                    msg = "请输入字段值";
                  }
                }
              });
            }
            if (msg !== "") {
              return this.$GlobalErrorConfirm("获取数据失败", msg);
            }
            this.isGetDataLoading = true;
            subgroup_test(params)
              .then((res) => {
                if (res && res.code === 200) {
                  let { field, list } = res.data;
                  this.fieldList = field;
                  this.dataset.source = list;

                  if (list && list instanceof Array && list.length) {
                    this.$GlobalSuccessMessage("获取数据成功");
                  } else {
                    this.$GlobalErrorConfirm("获取数据失败", "数据为空");
                  }

                  // this.resetFieldConfig()
                } else {
                  this.$GlobalErrorConfirm("获取数据失败", res.msg);
                }
              })
              .catch((err) => {
                this.$GlobalErrorConfirm("获取数据失败", err.msg);
              })
              .finally(() => {
                this.isGetDataLoading = false;
              });
          }
        })
        .catch((err) => {
          console.log("err: ", err);
        });
    },
    persistenceData() {
      Promise.all([
        this.validateDataSource(),
        this.validateInfoForm(),
        this.validateChartForm(),
        this.validateMapperForm(),
      ])
        .then(() => {
          if (this.isPersistenceLoading !== true) {
            this.isPersistenceLoading = true;
            console.log(this.esForm);
            let params = {
              ...this.form,
              type: this.form.type,

              parameter: JSON.stringify({
                sql: {
                  ...this.sqlForm,
                },
                es: {
                  ...this.esForm,
                },
                api: {
                  ...this.apiForm,
                },
                mapper: {
                  ...this.mapper,
                },
              }),
            };
            if (this.form.id) {
              subgroup_edit(params)
                .then((res) => {
                  if (res && res.code === 200) {
                    this.$GlobalSuccessMessage("编辑成功");
                    this.$emit("update");
                  } else {
                    this.$GlobalErrorConfirm("编辑失败", res.msg);
                  }
                })
                .catch((err) => {
                  this.$GlobalErrorConfirm("编辑失败", err.msg);
                })
                .finally(() => {
                  this.isPersistenceLoading = false;
                });
            } else {
              subgroup_add(params)
                .then((res) => {
                  if (res && res.code === 200) {
                    this.$GlobalSuccessMessage("新增成功");
                    this.$emit("update");
                  } else {
                    this.$GlobalErrorConfirm("新增失败", res.msg);
                  }
                })
                .catch((err) => {
                  this.$GlobalErrorConfirm("新增失败", err.msg);
                })
                .finally(() => {
                  this.isPersistenceLoading = false;
                });
            }
          }
        })
        .catch(() => {});
    },
    renderChart() {
      if (
        this.dataset &&
        this.dataset.dimensions instanceof Array &&
        this.dataset.source instanceof Array
      ) {
        this.option.dataset = this.dataset;
        this.$refs.chartDom.chartResize();
      } else {
        // console.log("dimensions: ", this.dataset.dimensions);
        // console.log("source: ", this.dataset.source);
      }
    },
    validateDataSource() {
      return new Promise((resolve, reject) => {
        this.$refs["dataSourceForm"].validate((dsValid) => {
          if (dsValid) {
            if (this.form.sourceType === "MYSQL") {
              this.validateForm("sqlForm")
                .then(() => {
                  resolve();
                })
                .catch(() => {
                  reject();
                });
            }

            if (this.form.sourceType === "API") {
              this.validateForm("apiForm")
                .then(() => {
                  resolve();
                })
                .catch(() => {
                  reject();
                });
            }

            if (this.form.sourceType === "ES") {
              resolve();
            }
          } else {
            reject();
            return false;
          }
        });
      });
    },

    validateForm(formName) {
      return new Promise((resolve, reject) => {
        if (this.$refs[formName]) {
          this.$refs[formName].validate((valid) => {
            if (valid) {
              resolve();
            } else {
              reject();
              return false;
            }
          });
        }
      });
    },

    validateInfoForm() {
      return this.validateForm("infoForm");
    },
    validateChartForm() {
      return this.validateForm("chartForm");
    },
    validateMapperForm() {
      return this.validateForm("mapperForm");
    },

    clearESData() {
      this.esForm.group = [];
      this.esForm.where.chd = [];
    },

    /**
     * 清除表单 内容/验证
     */
    resetChartForm() {
      this.$refs["infoForm"].resetFields();
      this.$refs["chartForm"].resetFields();
      this.$refs["mapperForm"].resetFields();

      if (this.$refs["sqlForm"]) this.$refs["sqlForm"].resetFields();
      if (this.$refs["apiForm"]) this.$refs["apiForm"].resetFields();
      this.clearESData();
    },

    resetMapperConfig() {
      this.$refs["mapperForm"].resetFields();
      this.mapper.dimensions = "";
      this.mapper.xField = "";
      this.mapper.yField = "";
    },
    resetChartData() {
      this.fieldList = [];
      this.dataset.source = [];
    },

    resetConfigData() {
      this.resetChartForm();

      this.form.id = null;
      this.form.name = ""; // 组件名称
      this.form.description = ""; // 组件描述
      this.form.type = ""; // 上级分类id
      this.form.typeName = ""; // 上级分类id

      this.form.sourceType = ""; // 数据类型
      this.form.datasource = ""; // 数据来源

      if (
        this.dbTypeList &&
        this.dbTypeList instanceof Array &&
        this.dbTypeList.length
      ) {
        this.form.sourceType = this.dbTypeList[0].value;
        this.sourceTypeChange();
      }

      this.form.echartId = ""; // 图表模板id
      this.form.chartType = ""; // 图表模板分类id

      if (
        this.chartTree &&
        this.chartTree instanceof Array &&
        this.chartTree.length
      ) {
        this.form.chartType = this.chartTree[0].type;
        this.chartTypeChange();
      }

      this.sqlForm.datasql = "";

      this.esForm.group = [];
      this.esForm.where.chd = [];

      this.apiForm.url = "";
      this.apiForm.param = "";

      this.mapper.dimensions = "";
      this.mapper.xField = "";
      this.mapper.yField = "";
    },

    editConfigData(id, group) {
      this.isEdit = true;
      if (this.form.id === id) {
        // 相同点击
      } else {
        this.resetConfigData();

        if (group) {
          this.form.type = group.id;
          this.form.typeName = group.name;
        }

        this.getComponentInfoById(id);
      }
    },

    addConfigData(group) {
      this.isEdit = false;
      this.resetConfigData();

      this.form.type = group.id;
      this.form.typeName = group.name;
    },
    chartTypeChange() {
      let ct = this.chartTree.find((c) => c.type === this.form.chartType);
      if (
        ct &&
        ct.reportEchartsList &&
        ct.reportEchartsList instanceof Array &&
        ct.reportEchartsList.length
      ) {
        this.form.echartId = ct.reportEchartsList[0].id;
        this.chartTemplateChange();
      }
    },
    chartTemplateChange() {
      let template = this.chartList.find(
        (item) => item.id === this.form.echartId
      );
      if (template && template.parameter) {
        try {
          this.option = JSON.parse(template.parameter);
          this.renderChart();
        } catch (e) {
          console.error("图表模板转换异常");
          console.error("图表模板: ", template.parameter);
        }
      }
    },
    handleDimensions() {
      this.mapper.dimensions = `${this.mapper.xField},${this.mapper.yField}`;
    },
    sourceTypeChange() {
      let st = this.dbTypeList.find(
        (item) => item.value === this.form.sourceType
      );
      if (
        st &&
        st.children &&
        st.children instanceof Array &&
        st.children.length
      ) {
        this.form.datasource = st.children[0].value;
        this.dataSourceChange();
      }

      // 重置表单
      if (this.$refs["sqlForm"]) this.$refs["sqlForm"].resetFields();
      if (this.$refs["apiForm"]) this.$refs["apiForm"].resetFields();
      // 重置数据
      this.resetChartData();
      // 重置映射配置
      this.resetMapperConfig();
    },
  },
  mounted() {
    this.getDataSourceList();
    this.getChartList();
  },
};
</script>

<style scoped lang="scss">
.report-component-container {
  display: flex;
  flex-direction: column;
  height: 100%;

  .report-component-header-wrap {
    height: 50px;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid #eee;
    padding-bottom: 18px;

    .header-title {
      font-size: 18px;
    }
  }

  .report-component-body-wrap {
    display: flex;
    /*flex: 1;*/
    height: calc(100% - 48px);
    width: 100%;
    overflow-y: scroll;

    .report-component-info-wrap {
      width: calc(50% - 1px);
      height: 100%;
      padding: 0 80px 0 62px;
      box-sizing: border-box;

      .field-row {
        margin-bottom: 12px;
      }
    }

    .line {
      height: calc(100% - 12px);
      margin-top: 12px;
      width: 1px;
      border-right: 1px solid #eee;
    }

    .report-component-preview-wrap {
      width: 50%;
      height: 100%;
      padding: 0 80px;
      box-sizing: border-box;

      .component-preview-table-wrap {
        width: 100%;
        height: 200px;
        overflow-y: scroll;
      }

      .component-chart-wrap {
        width: 100%;
        height: 500px;
        margin-top: 50px;
      }
    }
  }
}
</style>
